<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<!-- 

手写Promise：包含then和catch方法


-->
<script>
    // var MyPromise = (function (window) {
    //     // 三个状态会多次使用到所以不建议写死
    //     const PENDING = 'pending'
    //     const RESOLVED = 'resolved'
    //     const REJECTED = 'rejected'
    //     // 返回一个class，所以可以实例化
    //     return class MyPromise {
    //         // 构造函数，参数是一个回调函数
    //         constructor(fn) {
    //             // 默认状态
    //             this.status = PENDING
    //             // 成功状态的数据
    //             this.value = undefined
    //             // 失败状态的数据
    //             this.reason = undefined
    //             // 成功的
    //             this.onFulfilledCallbacks = []
    //             //失败的
    //             this.inRejectedCallbacks = []
    //             // 声明成功的方法
    //             const resolve = value => {
    //                 // 只有状态是等待时修改
    //                 if (this.status === PENDING) {
    //                     // 修改为成功状态
    //                     this.status = RESOLVED
    //                     // 保存成功数据
    //                     this.value = value
    //                     // 状态变为成功就执行成功队列里的函数
    //                     this.onFulfilledCallbacks.forEach(cb => cb())
    //                 }
    //             }
    //             // 声明失败的方法
    //             const reject = value => {
    //                 // 只有状态是等待时修改
    //                 if (this.status === PENDING) {
    //                     // 修改为失败状态
    //                     this.status = REJECTED
    //                     // 保存失败数据
    //                     this.reason = value
    //                     // 状态变为失败就执行失败队列里的函数
    //                     this.inRejectedCallbacks.forEach(cb => cb())
    //                     // this.inRejectedCallbacks.map(cb => cb())
    //                 }
    //             }
    //             try {
    //                 fn(resolve, reject)
    //             } catch (error) {
    //                 // 出现错误把改为失败状态
    //                 reject(error)
    //             }
    //         }
    //         // 成功回调，失败回调
    //         then(onFulfilled, inRejected) {
    //             // 状态为成功执行第一个回调，状态为失败执行第二个回调
    //             if (this.status === RESOLVED) {
    //                 // 调用第一个成功的回调
    //                 onFulfilled && onFulfilled(this.value)
    //             }
    //             if (this.status === REJECTED) {
    //                 // 调用第二个失败的回调
    //                 inRejected && inRejected(this.reason)
    //             }
    //             // 因为构造函数里的异步代码，起初是不会执行的，所以状态为等待
    //             if (this.status === PENDING) {
    //                 // 把成功的回调添加到队列中
    //                 // 由于要接收参数所以使用回调函数就可以接收参数
    //                 this.onFulfilledCallbacks.push(() => {
    //                     onFulfilled && onFulfilled(this.value)
    //                 })
    //                 // 把失败的回调添加到队列中
    //                 this.inRejectedCallbacks.push(() => {
    //                     inRejected && inRejected(this.reason)
    //                 })
    //             }
    //         }
    //     }

    // })(window)




    var MyPromise = (function (window) {
        const PENDING = 'pending';
        const RESOLVED = 'resolved';
        const REJECTED = 'rejected';
        return class MyPromise {
            constructor(fn) {
                // 状态
                const status = PENDING;
                // 成功数据
                const rveValue = undefined;
                // 失败数据
                const rjtValue = undefined;
                // 成功的
                const rveYes = [];
                // 失败的
                const rjtNo = [];

                // 声明成功的办法
                const resolve = value => {
                    if (this.status === PENDING) {
                        this.rveValue = value;
                        this.status = RESOLVED;
                        this.rveYes.forEach(cb => cb());
                    }
                }


                // 声明失败的办法
                const reject = value => {
                    if (this.status === REJECTED) {
                        this.rjtValue = value;
                        this.status = REJECTED;
                        this.rjtNo.forEach(cb => cb())
                    }
                }
                try {
                    fn(resolve, reject)
                } catch (error) {
                    reject(error)
                }
            }
            // 成功的回调，失败的回调
            then(rve, rjt) {
                if (this.status === RESOLVED) {
                    rve && rve(this.value);
                }
                if (this.status === REJECTED) {
                    rjt && rjt(this.value)
                }
                // 为了支持异步代码
                if (this.status === PENDING) {
                    this.rveYes.push(() => {
                        rve && rve(this.value)
                    });
                    this.rjtNo.push(() => {
                        rjt && rjt(this.value);
                    })
                }


            }

        }


        // 测试
        new MyPromise((resolve, reject) => {
            setTimeout(() => {
                if (Math.random() > 0.5) {
                    resolve('成功')
                } else {
                    reject('失败')
                }
            }, 3000)
        })
            .then((res) => {
                console.log('then1第一个回调', res);

            }, err => {
                console.log('then2第一个回调', err);

            })


    })(window)
    var a = new MyPromise();
    console.log(a);

</script>

</html>